package com.sikaryofficial.backend.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sikaryofficial.backend.domain.dto.req.prize.PrizeOwnerListReq;
import com.sikaryofficial.backend.domain.dto.req.prize.PrizeRedeemListReq;
import com.sikaryofficial.backend.domain.dto.resp.prize.PrizeRedeemDTO;
import com.sikaryofficial.backend.domain.entity.PrizeRedeem;
import com.sikaryofficial.backend.domain.vo.export.PrizeWinnerExportVO;
import com.sikaryofficial.backend.mapper.PrizeRedeemMapper;
import com.sikaryofficial.backend.service.IPrizeRedeemService;
import com.sikaryofficial.common.core.exception.ServiceException;
import com.sikaryofficial.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 奖品兑换Service业务层处理
 *
 * @author qinjinyuan
 * @date 2024-07-15
 */
@Service
public class PrizeRedeemServiceImpl extends ServiceImpl<PrizeRedeemMapper, PrizeRedeem> implements IPrizeRedeemService {
    @Autowired
    private PrizeRedeemMapper prizeRedeemMapper;

    /**
     * 奖品兑换记录
     *
     * @param prizeIds     礼品ID
     * @param businessType 业务类型
     * @return 统计集合
     */
    @Override
    public Map<Long, Integer> prizeRedeemCount(List<Long> prizeIds, Integer businessType) {
        if (CollUtil.isEmpty(prizeIds)) {
            return Maps.newHashMap();
        }
        List<PrizeRedeem> prizeRedeems = prizeRedeemMapper.prizeRedeemCount(prizeIds, businessType);
        if (CollUtil.isEmpty(prizeRedeems)) {
            return Maps.newHashMap();
        }
        return prizeRedeems.stream().filter(item -> Objects.nonNull(item.getRedeemNumber()))
                .collect(Collectors.toMap(PrizeRedeem::getPrizeId, PrizeRedeem::getRedeemNumber, (k1, k2) -> k1));
    }

    /**
     * 奖品兑换记录
     *
     * @param prizeId      礼品ID
     * @param businessType 业务类型
     * @return 统计集合
     */
    @Override
    public Map<Long, Integer> prizeRedeemSignCount(Long prizeId, Integer businessType) {
        List<Long> prizeIds = Lists.newArrayList();
        prizeIds.add(prizeId);
        return prizeRedeemCount(prizeIds, businessType);
    }

    /**
     * 个人奖品列表 （兑奖和转盘聚合）
     *
     * @param customerPage
     * @param req
     * @return
     */
    @Override
    public IPage<PrizeRedeemDTO> ownerRedeemList(Page<PrizeRedeemDTO> customerPage, PrizeOwnerListReq req) {
        IPage<PrizeRedeemDTO> prizeRedeemPageList = prizeRedeemMapper.ownerRedeemList(customerPage, req);
        if (Objects.isNull(prizeRedeemPageList) || CollUtil.isEmpty(prizeRedeemPageList.getRecords())) {
            return new Page<>(1, 7, 0);
        }
        return prizeRedeemPageList;
    }

    /**
     * 根据活动ID，获取用户中奖结果
     *
     * @param prizeRedeemId
     * @return
     */
    @Override
    public PrizeRedeemDTO getOwnerRedeemDetail(Long prizeRedeemId) {
        return prizeRedeemMapper.getOwnerRedeemDetail(prizeRedeemId);
    }

    /**
     * 根据活动ID，获取用户中奖结果
     *
     * @param activityResultId
     * @return
     */
    @Override
    public PrizeRedeemDTO getOwnerRedeemDetailByResultId(Long activityResultId) {
        return prizeRedeemMapper.getOwnerRedeemDetailByResultId(activityResultId);
    }

    @Override
    public int countActivityResult(Long userId){
        return prizeRedeemMapper.countActivityResult(userId);
    }
    @Override
    public int countPrizeRedeem(Long userId){
        return prizeRedeemMapper.countPrizeRedeem(userId);
    }

    @Override
    public IPage<PrizeRedeemDTO> prizeRedeemPageList(Page<PrizeRedeemDTO> customerPage, PrizeRedeemListReq req) {
        IPage<PrizeRedeemDTO> prizeRedeemPageList = prizeRedeemMapper.prizeRedeemPageList(customerPage, req);
        if (Objects.isNull(prizeRedeemPageList) || CollUtil.isEmpty(prizeRedeemPageList.getRecords())) {
            return new Page<>(1, 7, 0);
        }
        return prizeRedeemPageList;
    }

    /**
     * 兑奖记录
     *
     * @param prizeId  奖品ID
     * @param prizeNum 奖品数量
     * @return true or false
     */
    @Override
    public PrizeRedeem prizeRedeemSave(Long prizeId, Integer prizeNum, Long userAddressId, Integer prizeGrantStatus) {
        PrizeRedeem prizeRedeem = new PrizeRedeem();
        prizeRedeem.setPrizeRedeemId(IdWorker.getId());
        prizeRedeem.setPrizeId(prizeId);
        prizeRedeem.setRedeemNumber(prizeNum);
        prizeRedeem.setUserAddressId(userAddressId);
        prizeRedeem.setCreatedBy(SecurityUtils.getUserId());
        prizeRedeem.setCreatedTime(new Date());
        prizeRedeem.setCreatedName(SecurityUtils.getUsername());
        prizeRedeem.setPrizeGrantStatus(prizeGrantStatus);
        this.save(prizeRedeem);
        return prizeRedeem;
    }

	@Override
	public List<PrizeWinnerExportVO> prizeWinnerExport(Long activityId) {
		return prizeRedeemMapper.prizeWinnerExport(activityId);
	}


	/**
	 * 每个用户每月最多兑换 3 次
	 *
	 * @param userId
	 * @param monthlyTotal 限制总次数
	 * @return
	 */
	@Override
	public boolean canExchangeByUser(Long userId, int monthlyTotal) {
		if (userId == null) {
			throw new ServiceException("User ID cannot be null");
		}
		// 查询用户在当前月份内的兑换次数
		int count = countMonthlyRedeems(userId, null);
		// 判断兑换次数是否小于限制次数
		return count < monthlyTotal; // 如果小于，则允许兑换
	}

	/**
	 * 每个礼品每月只能兑换 1 次
	 *
	 * @param userId        用户ID
	 * @param prizeId       礼品ID
	 * @param prizeLimitNum 礼品限制数量
	 * @return
	 */
	@Override
	public boolean canExchangeByPrize(Long userId, Long prizeId, int prizeLimitNum) {
		if (userId == null || prizeId == null) {
			throw new ServiceException("User ID and Prize ID cannot be null");
		}
		// 查询用户在当前月份内的兑换次数
		int count = countMonthlyRedeems(userId, prizeId);
		// 判断兑换次数是否等于限制次数
		return count < prizeLimitNum;
	}

	private int countMonthlyRedeems(Long userId, Long prizeId) {
		// 1. 获取当前日期
		LocalDate now = LocalDate.now();
		// 2. 计算当月的第一天
		LocalDate firstDayOfMonth = now.withDayOfMonth(1);
		// 3. 计算当月的最后一天
		LocalDate lastDayOfMonth = now.withDayOfMonth(now.lengthOfMonth());
		// 4. 转换为 LocalDateTime 类型
		LocalDateTime startTime = firstDayOfMonth.atStartOfDay();
		LocalDateTime endTime = lastDayOfMonth.atTime(LocalTime.MAX);
		if (prizeId == null) {
			return prizeRedeemMapper.countByUserIdAndTimeRange(userId, startTime, endTime);
		} else {
			return prizeRedeemMapper.countByUserIdAndPrizeIdAndTimeRange(userId, prizeId, startTime, endTime);
		}
	}
}
